#include <vtkForceDirectedLayoutStrategy.h>
#include <vtkGraphLayoutView.h>
#include <vtkMutableUndirectedGraph.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>

#include <vtkArcSource.h>
#include <vtkPolyDataMapper.h>
#include "vtkPolygon.h"
#include "vtkProperty.h"

#include "vtkLookupTable.h"
#include "vtkMinimalStandardRandomSequence.h"
#include "vtkCellData.h"
#include "vtkFloatArray.h"

#include "vtkGlyph3DMapper.h"
#include "vtkSphereSource.h"

#include "vtkInteractorStyleTrackballCamera.h"
#include "vtkTransform.h"
#include "vtkTransformPolyDataFilter.h"



int main(int, char*[]) {
    vtkNew<vtkRenderer> renderer;
    vtkNew<vtkRenderWindow> renderWindow;
    renderWindow->SetWindowName("RegularPolygonSource");
    renderWindow->AddRenderer(renderer);
    vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
//    renderWindowInteractor->SetInteractorStyle(vtkNew<vtkInteractorStyleTrackballCamera>)
    renderWindowInteractor->SetRenderWindow(renderWindow);


    vtkNew<vtkNamedColors> colors;


    const int RowCount = 12;
    const int ColCount = 10;
//    const double RowDegree = vtkMath::Pi() * 2 / RowCount;
    const double Radius = 500;
    const int AreaAvgRadius = Radius / ColCount;
    const int ArcSegmentCount = 1;
//    double ArcSegmentDegree = RowDegree / ArcSegmentCount;
    const double MaxRowIntervalDegree = vtkMath::Pi() * 2 / RowCount;

    // 创建数据
    std::vector<std::vector<double>> dataList(RowCount);
    std::vector<double> azimuthList(RowCount);
    for (int i = 0; i < RowCount; ++i) {
        dataList[i].resize(ColCount);
        azimuthList[i] = (vtkMath::Pi() * 2 / RowCount) * i;
        for (int j = 0; j < ColCount; ++j) {
            dataList[i][j] = j;
        }
    }



    vtkNew<vtkCellArray> allPolygons;
    vtkNew<vtkPoints> allPoints;
    vtkNew<vtkPolyData> polygonPolyData;

    for (int i = 0; i < RowCount; ++i) {

//        double degree = RowDegree * i;
        double degree = azimuthList[i];
        if(degree > vtkMath::Pi() * 2) {
            break;
        }

        double nextDegree = 0;
        if (i < RowCount - 1) {
            nextDegree = azimuthList[i + 1];
        }

        // 限制绘制方位角最大绘制读数
        nextDegree = vtkMath::Max(nextDegree, MaxRowIntervalDegree + degree);

        double ArcSegmentDegree = (nextDegree - degree) / ArcSegmentCount;

        for (int j = 0; j < ColCount; ++j) {

            vtkNew<vtkPolygon> polygon;
            polygon->GetPointIds()->SetNumberOfIds((ArcSegmentCount + 1) * 2);
            vtkIdType numberOfPoints = allPoints->GetNumberOfPoints();

            double radius0 = j * AreaAvgRadius;
            double radius1 = (j + 1) * AreaAvgRadius;

            for (int k = 0; k < ArcSegmentCount + 1; ++k) {
                double d0 = degree + (ArcSegmentDegree) * k;
                double x0 = cos(d0) * radius0;
                double y0 = sin(d0) * radius0;
                allPoints->InsertNextPoint(x0, y0, 0.0);

                double d1 = degree + (ArcSegmentDegree) * k;
                double x1 = cos(d1) * radius1;
                double y1 = sin(d1) * radius1;
                allPoints->InsertNextPoint(x1, y1, 0.0);

                polygon->GetPointIds()->SetId(k, numberOfPoints + (ArcSegmentCount - k));
                polygon->GetPointIds()->SetId(k + ArcSegmentCount + 1, numberOfPoints + ArcSegmentCount + 1 + k);
            }

            allPolygons->InsertNextCell(polygon);
        }
    }

    polygonPolyData->SetPoints(allPoints);
    polygonPolyData->SetPolys(allPolygons);


    // 测试非世界坐标系旋转
    vtkNew<vtkTransform> transL1;
    transL1->RotateY(90);

    vtkNew<vtkTransformPolyDataFilter> transF;
//    transF->SetInputConnection(polygonPolyData->GetOutputPort());
    transF->SetInputData(polygonPolyData);
    transF->SetTransform(transL1);


    vtkNew<vtkPolyDataMapper> mapper;
//    mapper->SetInputData(polygonPolyData);
    mapper->SetInputConnection(transF->GetOutputPort());



//    SetScalars(vtkDataArray* da);
//    polygonPolyData->GetCellData()->SetScalars();


//    vtkNew<vtkUnsignedCharArray> cellData;
//    cellData->SetNumberOfComponents(3);
//    cellData->SetNumberOfTuples(ringActorData->GetNumberOfCells());
//
//
//    vtkNew<vtkColorTransferFunction> colorTransferFunction;
//
//    double color0[3] = {13.0/255.0, 0, 198.0/255.0};
//    double color1[3] = {0, 9.0/255.0, 1};
//    double color2[3] = {0, 182.0/255.0, 1};
//    double color3[3] = {0, 51.0/255.0, 1};
//    double color4[3] = {0, 1, 149.0/255.0};
//    double color5[3] = {1, 46.0/255.0, 0};
//    double color6[3] = {201.0/255.0, 0, 0};
//    colorTransferFunction->AddRGBPoint(0.0, color0[0], color0[1], color0[2]);
//    colorTransferFunction->AddRGBPoint(8.0, color1[0], color1[1], color1[2]);
//    colorTransferFunction->AddRGBPoint(16.0, color2[0], color2[1], color2[2]);
//    colorTransferFunction->AddRGBPoint(24.0, color3[0], color3[1], color3[2]);
//    colorTransferFunction->AddRGBPoint(32.0, color4[0], color4[1], color4[2]);
//    colorTransferFunction->AddRGBPoint(40.0, color5[0], color5[1], color5[2]);
//    colorTransferFunction->AddRGBPoint(48.0, color6[0], color6[1], color6[2]);
//
//    for (int i = 0; i < 360; i++) {
//        for (int j = 0; j < 400; j++) {
//            double data = listThree.list[i][j];
//            double color[3];
//            colorTransferFunction->GetColor(data, color);
//            cellData->InsertTuple(i * 360 + j, color);
//        }
//    }
//
//    ringActorData->GetCellData()->SetScalars(cellData);


    vtkNew<vtkActor> actor;
    actor->SetMapper(mapper);
    actor->GetProperty()->EdgeVisibilityOn();
    renderer->AddActor(actor);

    actor->SetPosition(300, 0, 0);



//    actor->SetUserTransform(transL1);

    vtkNew<vtkSphereSource> sphere;
    sphere->SetRadius(100);
    vtkNew<vtkPolyDataMapper> sphereMapper;
    sphereMapper->SetInputConnection(sphere->GetOutputPort());
    vtkNew<vtkActor> sphereActor;
    sphereActor->SetMapper(sphereMapper);
    sphereActor->GetProperty()->SetColor(255, 0, 0);
    renderer->AddActor(sphereActor);

    renderWindow->Render();
    renderWindowInteractor->Initialize();
    renderWindowInteractor->Start();


    return EXIT_SUCCESS;
}